﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine.UI;

// 静态方式创建动画，需要手动完成：切割图集、
// 通过脚本自动生成：动画和动画控制器文件、生成预设体文件
public class CreateSan10Anim : Editor
{
	// 原始序列帧动画图
	public static string mOriginalImage = "";

	// 根路径，和 “原始序列帧动画图” 同名
	private static string mRootPath = "Assets/Resources/Soldiers/qingbubing";
	// 原始序列帧动画图集路径
	private static string mImagePath = mRootPath + "/Image";
	// 生成出的Prefab的路径
	private static string mPrefabPath = mRootPath + "/Prefab";
	// 生成出的AnimationController的路径
	private static string mAnimationControllerPath = mRootPath + "/AnimationController";
	// 生成出的Animation的路径
	private static string mAnimationPath = mRootPath + "/Animation";



	enum ESoldier_Direction
	{
		eSDir_Right_Up = 0,//↗
		eSDir_Right = 1,//→
		eSDir_Right_Down = 2,//↘
		eSDir_Down = 3,//↓
		eSDir_Left_Down = 4,//↙
		eSDir_Left = 5,//←
		eSDir_Left_Up = 6,//↖
		eSDir_Up = 7,//↑
	};

	enum ESoldier_AnimType
	{
		eSAnimType_Walk = 0,
		eSAnimType_Attack = 1,
		eSAnimType_Thump = 2,
		eSAnimType_Stand = 3,
		eSAnimType_BeAttack = 4,
		eSAnimType_Dead = 5,
	}

    // 动画片段名
    static string[,] mClipNames = new string[8, 6]
    {
        { "right_up_walk", "right_up_attack", "right_up_thump", "right_up_stand", "right_up_be_atk", "right_up_dead" },
        { "right_walk", "right_attack", "right_thump", "right_stand", "right_be_atk", "right_dead" },
        { "right_down_walk", "right_down_attack", "right_down_thump", "right_down_stand", "right_down_be_atk", "right_down_dead" },
        { "down_walk", "down_attack", "down_thump", "down_stand", "down_be_atk", "down_dead" },
        { "left_down_walk", "left_down_attack", "left_down_thump", "left_down_stand", "left_down_be_atk", "left_down_dead" },
        { "left_walk", "left_attack", "left_thump", "left_stand", "left_be_atk", "left_dead" },
        { "left_up_walk", "left_up_attack", "left_up_thump", "left_up_stand", "left_up_be_atk", "left_up_dead" },
        { "up_walk", "up_attack", "up_thump", "up_stand", "up_be_atk", "up_dead" },
    };

    // 每个序列帧动画长度
    const int SOLDIER_ANIM_LEN = 8;
    // 每个方向的所有动画片段
    static AnimationClip[,] mAnimClips = null;
    // 动画控制器
    static AnimatorController mAnimatorController = null;
    // 生成预设体的 Animator 组件
    static Animator mAnimator = null;

    static Sprite[] mSprites = null;
    static GameObject testPrefab = null;



    // 创建所有必需的文件夹
    private static void CreateFolder()
	{
		Directory.CreateDirectory(mRootPath);
		Directory.CreateDirectory(mImagePath);
		Directory.CreateDirectory(mPrefabPath);
		Directory.CreateDirectory(mAnimationControllerPath);
		Directory.CreateDirectory(mAnimationPath);

		AssetDatabase.Refresh();
	}

	// 创建所有动画片段
	private static void CreateAnimClips(Sprite[] sprites)
	{
        if (mAnimClips != null)
        {
            return;
        }

        if (sprites == null)
        {
            return;
        }

        EditorCurveBinding curveBinding = new EditorCurveBinding();
        curveBinding.type = typeof(SpriteRenderer);
        curveBinding.path = "";
        curveBinding.propertyName = "m_Sprite";

        int sizeEDir = System.Enum.GetNames((new ESoldier_Direction()).GetType()).Length;
        int sizeEAnimType = System.Enum.GetNames((new ESoldier_AnimType()).GetType()).Length;

        mAnimClips = new AnimationClip[sizeEDir, sizeEAnimType];
        for (int iDir = 0; iDir < sizeEDir; ++iDir)
        {
            for (int iAnimType = 0; iAnimType < sizeEAnimType; ++iAnimType)
            {
                // 原始图集起始索引 == ESoilder_Direction + 1 + 8 x ESoilder_AnimType
                int originIndex = iDir + 1 + 8 * iAnimType;
                // Unity中，动画起始索引 == （原始图集起始索引 - 1）x 8
                int startIndex = (originIndex - 1) * 8;

                // 创建关键帧
                ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[SOLDIER_ANIM_LEN];
                //动画长度是按秒为单位，1/10就表示1秒切10张图片，根据项目的情况可以自己调节
                float frameTime = 1.0f / 10.0f;
                for (int iFrame = 0; iFrame < SOLDIER_ANIM_LEN; ++iFrame)
                {
                    keyFrames[iFrame] = new ObjectReferenceKeyframe();
                    keyFrames[iFrame].time = frameTime * iFrame;
                    keyFrames[iFrame].value = sprites[iFrame + startIndex];
                }

                AnimationClip clip = new AnimationClip();
                clip.frameRate = 30;//动画帧率，30比较合适
                clip.name = mClipNames[iDir, iAnimType];

                // 设置动画循环播放
                UnityEditor.AnimationClipSettings clipSetting = AnimationUtility.GetAnimationClipSettings(clip);
                clipSetting.loopTime = true;
                AnimationUtility.SetAnimationClipSettings(clip, clipSetting);
                AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);

                mAnimClips[iDir, iAnimType] = clip;

                AssetDatabase.CreateAsset(clip, mAnimationPath + "/" + mClipNames[iDir, iAnimType] + ".anim");
                AssetDatabase.SaveAssets();
            }//end for: iAnimType
        }//end for: iDir
    }

	// 创建动画控制器
	private static void CreateAnimController()
	{
        if (mAnimClips == null)
        {
            return;
        }

        // 显式指定一个默认的动画片段
        //AnimationClip defaultClip = mAnimClips[(int)ESoldier_Direction.eSDir_Left_Up, (int)ESoldier_AnimType.eSAnimType_Dead];
        //defaultClip.name = "left_up_dead";

        // 这个动画播的是右上的，好像不对
        AnimationClip right_stand_Clip = mAnimClips[(int)ESoldier_Direction.eSDir_Right, (int)ESoldier_AnimType.eSAnimType_Stand];
        right_stand_Clip.name = "right_stand";

        AnimationClip right_walk_Clip = mAnimClips[(int)ESoldier_Direction.eSDir_Right, (int)ESoldier_AnimType.eSAnimType_Walk];
        right_walk_Clip.name = "right_walk";

        // stand
        AnimationClip right_up_stand_Clip = mAnimClips[(int)ESoldier_Direction.eSDir_Right_Up, (int)ESoldier_AnimType.eSAnimType_Stand];
        right_up_stand_Clip.name = "right_up_stand";
        AnimationClip right_down_stand_Clip = mAnimClips[(int)ESoldier_Direction.eSDir_Right_Down, (int)ESoldier_AnimType.eSAnimType_Stand];
        right_down_stand_Clip.name = "right_down_stand";
        AnimationClip left_down_stand_Clip = mAnimClips[(int)ESoldier_Direction.eSDir_Left_Down, (int)ESoldier_AnimType.eSAnimType_Stand];
        left_down_stand_Clip.name = "left_down_stand";
        AnimationClip left_up_stand_Clip = mAnimClips[(int)ESoldier_Direction.eSDir_Left_Up, (int)ESoldier_AnimType.eSAnimType_Stand];
        left_up_stand_Clip.name = "left_up_stand";


        if (mAnimatorController == null)
        {
            // 根据动画片段，创建动画控制器
            mAnimatorController = AnimatorController.CreateAnimatorControllerAtPath(mAnimationControllerPath + "/" + "qingbubing" + ".controller");
            AnimatorControllerLayer layer = mAnimatorController.layers[0];
            AnimatorStateMachine sm = layer.stateMachine;

            // 1. 最初始版本
            //AnimatorState state = sm.AddState(right_stand_Clip.name);
            //state.motion = right_stand_Clip;
            //sm.defaultState = state;

            // 这个 AnyState 是干嘛的，还是没太明白
            //sm.AddAnyStateTransition(state);

            // 2. 第一次修改后的版本
            //AnimatorState state = sm.AddState("stand");
            //state.motion = right_stand_Clip;
            //sm.defaultState = state;

            // 没用上
            //mAnimatorController.AddMotion(right_up_stand_Clip);
            //mAnimatorController.AddMotion(right_down_stand_Clip);
            //mAnimatorController.AddMotion(left_down_stand_Clip);
            //mAnimatorController.AddMotion(left_up_stand_Clip);

            // 3. 测试混合权重动画效果的版本
            BlendTree tree;
            AnimatorState blendState = mAnimatorController.CreateBlendTreeInController("", out tree);
            tree.blendType = BlendTreeType.SimpleDirectional2D;
            tree.blendParameter = "MoveX";
            tree.blendParameterY = "MoveY";
            tree.AddChild(right_up_stand_Clip, new Vector2(0, 1));
            tree.AddChild(right_down_stand_Clip, new Vector2(1, 0));
            tree.AddChild(left_down_stand_Clip, new Vector2(0, -1));
            tree.AddChild(left_up_stand_Clip, new Vector2(-1, 0));

            mAnimatorController.AddParameter("MoveX", AnimatorControllerParameterType.Float);
            mAnimatorController.AddParameter("MoveY", AnimatorControllerParameterType.Float);

            AssetDatabase.SaveAssets();
        }
    }

	// 加载原始图集资源
	private static void LoadImage()
	{
		Object[] originImages = AssetDatabase.LoadAllAssetsAtPath(mImagePath + "/qingbubing.png");
		mSprites = new Sprite[originImages.Length];

		// LoadAllAssetsAtPath() 返回一个 Object[]，需要先转成 Sprite[]，效率有点低
		for (int i = 0; i < originImages.Length; ++i)
		{
            if (originImages[i].GetType() == typeof(Texture2D))
            {
                Texture2D t2d = (Texture2D)originImages[i];
                Sprite s = Sprite.Create(t2d, new Rect(0, 0, t2d.width, t2d.height), Vector2.zero);
                mSprites[i] = s;
            }
            else if (originImages[i].GetType() == typeof(Sprite))
			{
				mSprites[i] = (Sprite)originImages[i];
			}
		}
	}

	// 创建预设体
	private static void CreatePrefab()
	{
        // 在内存中创建预设体 go
        GameObject go = new GameObject();
        go.name = "qingbubing_prefab";
        go.transform.localScale = new Vector3(5.0f, 5.0f, 5.0f);

        // 创建 SpriteRenderer 组件，并挂载到预设体 go 上
        SpriteRenderer spriteRender = go.AddComponent<SpriteRenderer>();

        // 把创建好的动画控制器，挂载都预设体 go 上
        if (mAnimator == null)
        {
            mAnimator = go.AddComponent<Animator>();
            mAnimator.runtimeAnimatorController = mAnimatorController;
            //mAnimator.SetFloat();
        }

        // 将缓存中的预设体写入文件
        PrefabUtility.SaveAsPrefabAsset(go, mPrefabPath + "/qingbubing_prefab.prefab");

        // 加载预设体资源
        //testPrefab = (GameObject)Resources.Load("Prefabs/qingbubing_prefab");
        testPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(mPrefabPath + "/qingbubing_prefab.prefab");

        DestroyImmediate(go);

        if (testPrefab != null)
        {
            //实例化预设体（默认在运行时，创建一个预设体）
            Instantiate(testPrefab);
        }
    }

    [MenuItem("MyTools/CreateSan10Anim", false, 1)]
    public static void Start()
    {
		CreateFolder();

		// 加载原始图集资源
		LoadImage();

		// 创建动画片段
		CreateAnimClips(mSprites);

		// 创建动画控制器
		CreateAnimController();

		// 创建预设体
		CreatePrefab();
	}
}
